/*
 * Copyright (c) 2020-2021, Bluetrum Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2020/12/10     greedyhao    The first version
 */

/**
 * Notice!
 * All functions or data that are called during an interrupt need to be in RAM.
 * You can do it the way exception_isr() does.
 */

#include <rtthread.h>
#include "board.h"


/*
********************************************************************************
 *                               ADC-MSH采样
********************************************************************************
 */
#define ADC_DEV_NAME        "adc0"      /* ADC 设备名称 */
#define ADC_DEV_CHANNEL     3           /* ADC 通道 */
#define REFER_VOLTAGE       330         /* 参考电压 3.3V,数据精度乘以100保留2位小数*/
#define CONVERT_BITS        (1 << 10)   /* 转换位数为12位 */

static int adc_vol_sample()
{
    rt_adc_device_t adc_dev;
    rt_uint32_t value, vol;
    rt_err_t ret = RT_EOK;

    /* 查找设备 */
    adc_dev = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME);
    if (adc_dev == RT_NULL)
    {
        rt_kprintf("adc sample run failed! can't find %s device!\n", ADC_DEV_NAME);
        return RT_ERROR;
    }

    /* 使能设备 */
    ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL);

    /* 读取采样值 */
    value = rt_adc_read(adc_dev, ADC_DEV_CHANNEL);
    rt_kprintf("the value is :%d \n", value);

    /* 转换为对应电压值 */
    vol = value * REFER_VOLTAGE / CONVERT_BITS;
    rt_kprintf("the voltage is :%d.%02d \n", vol / 100, vol % 100);

    /* 关闭通道 */
    ret = rt_adc_disable(adc_dev, ADC_DEV_CHANNEL);

    return ret;
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(adc_vol_sample, adc voltage convert sample);
/*
********************************************************************************
 *                               ADC-主线程循环采样
********************************************************************************
 */
int DemoAdcInit(void)
{
    rt_adc_device_t adc_dev;
    /* 查找设备 */
    adc_dev = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME);
    if (adc_dev == RT_NULL)
    {
        rt_kprintf("adc sample run failed! can't find %s device!\n", ADC_DEV_NAME);
        return RT_ERROR;
    }
    /* 使能设备 */
    rt_adc_enable(adc_dev, ADC_DEV_CHANNEL);
}
//INIT_DEVICE_EXPORT(DemoAdcInit);
static int DemoAdcGetValue(void)
{
    rt_adc_device_t adc_dev;
    rt_uint32_t value, vol;

    /* 查找设备 */
    adc_dev = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME);
    if (adc_dev == RT_NULL)
    {
      rt_kprintf("adc sample run failed! can't find %s device!\n", ADC_DEV_NAME);
      return RT_ERROR;
    }

    /* 读取采样值 */
    value = rt_adc_read(adc_dev, ADC_DEV_CHANNEL);
    rt_kprintf("the value is :%d \n", value);

    /* 转换为对应电压值 */
    vol = value * REFER_VOLTAGE / CONVERT_BITS;
    rt_kprintf("the voltage is :%d.%02d \n", vol / 100, vol % 100);
}
/*
********************************************************************************
 *                               ADC-线程采样
********************************************************************************
 */
/* 定义线程控制块 */
static rt_thread_t AdcDemo_thread  = RT_NULL;
rt_uint32_t  ADC_VoltageVal = 0;

static int AdcDemo_thread_entry(void* parameter);
static int AdcDemo_thread_entry(void* parameter)
{
    rt_adc_device_t adc_dev;
    rt_uint32_t value, vol;
    rt_err_t ret = RT_EOK;

    /* 查找设备 */
    adc_dev = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME);
    if (adc_dev == RT_NULL)
    {
      rt_kprintf("adc sample run failed! can't find %s device!\n", ADC_DEV_NAME);
      return RT_ERROR;
    }
    /* 使能设备 */
    ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL);
    while(1)
    {
      /* 读取采样值 */
      value = rt_adc_read(adc_dev, ADC_DEV_CHANNEL);
      rt_kprintf("the value is :%d \n", value);
      /* 转换为对应电压值 */
      vol = value * REFER_VOLTAGE / CONVERT_BITS;
      ADC_VoltageVal = vol;
      rt_kprintf("the voltage is :%d.%02d \n", vol / 100, vol % 100);
      rt_thread_mdelay(1000);
    }
    return ret;
}

void AdcDemo_ThreadInit(void)
{
    AdcDemo_thread =                     /* 线程控制块指针     */
    rt_thread_create( "AdcDemo",         /* 线程名字                */
            AdcDemo_thread_entry,        /* 线程入口函数        */
            RT_NULL,                     /* 线程入口函数参数 */
            1024,                        /* 线程栈大小     */
            3,                           /* 线程的优先级   */
            20);                         /* 线程时间片     */

   /* 启动线程，开启调度 */
   if (AdcDemo_thread != RT_NULL)
   {
     rt_thread_startup(AdcDemo_thread);
   }
}
INIT_APP_EXPORT(AdcDemo_ThreadInit);
MSH_CMD_EXPORT(AdcDemo_ThreadInit,AdcDemo);
/*
********************************************************************************
 *                                                       定时器线程
********************************************************************************
 */
/* 定时器的控制块 */
static rt_timer_t SliceTimer;
static unsigned char TimeCount = 0;
/* 定时器1超时函数 */
static void CycleTimeout(void *parameter)
{
  static unsigned char Job_IDX = 0;

  //rt_kprintf("periodic timer is timeout %d\n", TimeCount);
  TimeCount++;
  if(TimeCount >= 10)
  {
    TimeCount = 0;
    Job_IDX   = 0;
  }
  switch(Job_IDX)
  {
    case  0:AdcDemo_ThreadInit();break;
    case  1:          break;
    case  2:          break;
    case  3:          break;
    case  4:          break;
    case  5:          break;
    case  6:          break;
    case  7:          break;
    case  8:          break;
    case  9:          break;
    default:
      break;
  }
  Job_IDX++;
}

int ScanTimer_Init(void)
{
  /* 创建定时器1  周期定时器 */
  SliceTimer = rt_timer_create("SliceTimer", CycleTimeout,
                           RT_NULL, 100,
                           RT_TIMER_FLAG_PERIODIC);

  /* 启动定时器1 */
  if (SliceTimer != RT_NULL)
    rt_timer_start(SliceTimer);

  return 0;
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(ScanTimer_Init, SliceTimer);
/*
********************************************************************************
 *                                                                    主函数
********************************************************************************
 */
int main(void)
{
    uint32_t cnt = 0;
    uint8_t pin = rt_pin_get("PE.1");

    rt_pin_mode(pin, PIN_MODE_OUTPUT);
    rt_kprintf("Hello, world\n");
    /*
    uint8_t pin1 = rt_pin_get("PF.0");
    rt_pin_mode(pin1, PIN_MODE_OUTPUT);
    */
    while (1)
    {
        /*
        rt_pin_write(pin1, PIN_LOW);
        rt_hw_us_delay(500);
        rt_pin_write(pin1, PIN_HIGH);
        rt_hw_us_delay(500);
        rt_pin_write(pin1, PIN_LOW);
        rt_hw_us_delay(500);
        rt_pin_write(pin1, PIN_HIGH);
        */
        if (cnt % 2 == 0) {
            rt_pin_write(pin, PIN_LOW);
        } else {
            rt_pin_write(pin, PIN_HIGH);
        }
        cnt++;
        //DemoAdcGetValue();
        rt_thread_mdelay(1000);
    }

    return 0;
}




